package designmode.singleton;

/**
 * 单例模式
 * 也可以用枚举来实现，它在类加载的时候会初始化里面的所有的实例，而且 JVM 保证了它们不会再被实例化，所以它天生就是单例的。
 */
class Singleton {
    //volatile保证不会指令重排，可见的话new的三步操作对所有线程都可见，不会因为只看见两步而判断失误
    private volatile static Singleton singleton;

    // 私有化构造方法，防止通过new的方式创建对象
    private Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            //synchronized 保证原子性
            synchronized (Singleton.class) {
                if (singleton == null) {
                    //new有三个操作，不是原子性。分配内存空间；初始化对象；将对象指向内存三步
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

/**
 * 嵌套类实现单例
 */
class Singleton3 {

    private Singleton3() {
    }

    public static Singleton3 getInstance() {
        return Holder.instance;
    }

    // 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性
    private static class Holder {
        private static Singleton3 instance = new Singleton3();
    }
}
